package dryven.model.binding.form;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;

import javax.persistence.Entity;
import javax.persistence.Id;

import dryven.model.binding.fieldset.Field;
import dryven.model.binding.fieldset.FieldGroup;
import dryven.model.binding.fieldset.FieldSet;
import dryven.model.binding.proxy.Binding;
import dryven.request.controller.ControllerDescription;
import dryven.request.controller.result.ActionResult;
import dryven.util.BeanUtil;
import dryven.util.crypt.AESDecryption;
import dryven.util.crypt.AESEncryption;
import dryven.util.crypt.AESGeneratedKey;

public class FormSignatureEncoder {
	private AESGeneratedKey _key;
	private Binding<FieldSet> _fieldsetBinding;
	private FieldSet _fieldSet;
	private String _signSecret;
	private Map<Class<?>, Object> _boundModels;
	private String _errorURL;
	
	public FormSignatureEncoder(AESGeneratedKey key,
			Binding<FieldSet> fieldsetBinding, FieldSet fieldSet,
			String signSecret, Map<Class<?>, Object> boundModels, String requestPath) {
		super();
		_key = key;
		_fieldsetBinding = fieldsetBinding;
		_signSecret = signSecret;
		_boundModels = boundModels;
		_fieldSet = fieldSet;
		_errorURL = requestPath;
	}

	private FormSignature createUnencodedSignature() {
		BeanUtil beanUtil = new BeanUtil();
		FormSignature sig = new FormSignature();
		for (Class<?> modelType : _fieldSet.getModelTypes()) {
			int pk = 0;
			if (_boundModels != null) {
				Object model = _boundModels.get(modelType);
				if (model != null) {
					pk = beanUtil.getModelPK(model);
				}
			}
			sig.addValue(FormSignature.ModelType, modelType.getName() + ":"	+ pk);
		}
		sig.addValue(FormSignature.FieldSetType, _fieldsetBinding.toString());
		sig.addValue(FormSignature.ErrorActionType, _errorURL);
		return sig;
	}

	public String encode() {
		FormSignature signature = createUnencodedSignature();
		String result =  new AESEncryption(_key, signature.write(_signSecret)).encrypt();		
		return result;
	}
}
